﻿using System;
using Wisdom.Core;

namespace Wisdom.Core
{
    /// <summary>
    /// 描述：运用程序运行时，包括：运用程序如创建、实始化、和启动
    /// </summary>
    public sealed class AppRuntime : IFluentSyntax
    {
        #region Private Static Fields
        private static readonly AppRuntime instance = new AppRuntime();
        private static readonly object lockObj = new object();
        #endregion

        #region Private Fields
        private IApplication currentApplication;
        #endregion

        #region Ctor
        static AppRuntime() { }
        private AppRuntime() { }
        #endregion

        #region Public Static Properties
        /// <summary>
        /// 获得一个运用程序运行时 <c>ApplicationRuntime</c> 类实例.
        /// </summary>
        public static AppRuntime Instance
        {
            get { return instance; }
        }
        #endregion

        #region Public Properties
        /// <summary>
        /// 获得当前运用程序运行时的实例
        /// </summary>
        public IApplication CurrentApplication
        {
            get { return currentApplication; }
        }
        #endregion

        #region Public Methods
        /// <summary>
        /// 创建和初始化一个运用程序实例
        /// </summary>
        /// <param name="configSource">类 <see cref="IConfigSource"/> 实例</param>
        /// <returns>已初始化的运用程序实例.</returns>
        public static IApplication Create(IConfigSource configSource)
        {
            lock (lockObj)
            {
                if (instance.currentApplication == null)
                {
                    lock (lockObj)
                    {
                        if (configSource.Config == null ||
                            configSource.Config.Application == null)
                            throw new ConfigException("Either jiuzhou configuration or jiuzhou application configuration has not been initialized in the ConfigSource instance.");
                        string typeName = configSource.Config.Application.Provider;
                        if (string.IsNullOrEmpty(typeName))
                            throw new ConfigException("The provider type has not been defined in the ConfigSource.");
                        Type type = Type.GetType(typeName);
                        if (type == null)
                            throw new InfrastructureException("The application provider defined by type '{0}' doesn't exist.", typeName);
                        instance.currentApplication = (IApplication)Activator.CreateInstance(type, new object[] { configSource });
                    }
                }
            }
            return instance.currentApplication;
        }
        #endregion
    }
}